﻿//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
// Exo² - Tools - Studio
// Copyright (C) 2007-2008 Samuel Lacroix and Raphaël Legouge
//
// Distributed under GNU General Public License
// See the License folder for details
// http://www.codeplex.com/exo2 (eng)
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using SlimDX;

namespace Exo2Studio
{
    public partial class Studio : Form
    {
        public Studio()
        {
            InitializeComponent();

            this.aboutBox = new AboutBox();

            this.modules = new List<BasicModule.IBasicModule>();

            LoadModules();

        }

        private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void LoadModules()
        {
            BasicModule.IBasicModule Module = new ExefReaderModule.CExefReader(this.modulesToolStripMenuItem1);
            this.modules.Add(Module);

            Module = new ExefBuilderModule.CExefBuilderModule(this.modulesToolStripMenuItem1);
            this.modules.Add(Module);
        }

        List<BasicModule.IBasicModule> modules;

        private AboutBox aboutBox;

        private void openAboutAboxToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.aboutBox.ShowDialog();
        }

        private void Studio_FormClosing(object sender, FormClosingEventArgs e)
        {
            // TODO à faire avec des ressources
            //if (MessageBox.Show("Tous les modules vont être fermés.\nVoulez vous vraiment quitter ?", "Quitter ?", MessageBoxButtons.YesNo) == DialogResult.No)
                //e.Cancel = true;
        }

        private SlimDX.Direct3D9.Device device;
        private SlimDX.Direct3D9.Mesh mesh;


        private void createDeviceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Création du device
            SlimDX.Direct3D9.Direct3D direct3D = new SlimDX.Direct3D9.Direct3D();
            SlimDX.Direct3D9.AdapterInformation adapter = direct3D.Adapters.DefaultAdapter;
            int adapterIndex = adapter.Adapter;
            
            SlimDX.Direct3D9.DeviceType deviceType = SlimDX.Direct3D9.DeviceType.Hardware;
            IntPtr handle = this.pictureBox1.Handle;
            SlimDX.Direct3D9.CreateFlags createFlags = SlimDX.Direct3D9.CreateFlags.HardwareVertexProcessing;
            SlimDX.Direct3D9.PresentParameters presentParameters = new SlimDX.Direct3D9.PresentParameters();
            presentParameters.DeviceWindowHandle = handle;
            presentParameters.BackBufferHeight = this.pictureBox1.Height;
            presentParameters.BackBufferWidth = this.pictureBox1.Width;
            presentParameters.Windowed = true;
            presentParameters.BackBufferFormat = SlimDX.Direct3D9.Format.X8R8G8B8;

            if (!direct3D.CheckDeviceFormat(adapterIndex, deviceType, SlimDX.Direct3D9.Format.X8R8G8B8, SlimDX.Direct3D9.Usage.RenderTarget, SlimDX.Direct3D9.ResourceType.Surface, SlimDX.Direct3D9.Format.X8R8G8B8))
                // TODO à faire avec des ressources
                MessageBox.Show("Impossible de faire le rendu sur la surface...");
            try
            {
                this.device = new SlimDX.Direct3D9.Device(direct3D, adapterIndex, deviceType, handle, createFlags, presentParameters);
            }
            catch (SlimDX.Direct3D9.Direct3D9Exception /*exception*/)
            {
                MessageBox.Show("Erreur directX");
            }

            // Création de la lumière
            SlimDX.Direct3D9.Light light = new SlimDX.Direct3D9.Light();
            light.Type = SlimDX.Direct3D9.LightType.Directional;
            light.Ambient = new SlimDX.Color4(new SlimDX.Vector4(1.0f, 1.0f, 1.0f, 1.0f));
            light.Diffuse = new SlimDX.Color4(new SlimDX.Vector4(1.0f, 1.0f, 1.0f, 1.0f));
            light.Direction = new SlimDX.Vector3(-1.0f, -1.0f, 1.0f);
            light.Specular = new SlimDX.Color4(new SlimDX.Vector4(1.0f, 1.0f, 1.0f, 1.0f));
            this.device.SetLight(0, light);

            // Chargement du fichier x
            this.mesh = SlimDX.Direct3D9.Mesh.FromFile(this.device, "bunny.x", SlimDX.Direct3D9.MeshFlags.DoNotClip);
        }

        private void clearSurfaceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.device.Clear(SlimDX.Direct3D9.ClearFlags.Target, new SlimDX.Color4(new SlimDX.Vector4(0.0f, 0.0f, 0.0f, 0.0f)), 0.0f, 0);
        }

        private void presentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.device.Present();
        }

        private void renderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.device.EnableLight(0, true);

            SlimDX.Matrix viewMatrix = SlimDX.Matrix.Identity;
            viewMatrix.M41 = 0.0f;
            viewMatrix.M42 = 0.0f;
            viewMatrix.M43 = 0.1f;
            this.device.SetTransform(SlimDX.Direct3D9.TransformState.View, viewMatrix);

            float fov = 90.0f;
            float aspect = ((float)this.pictureBox1.Width) / this.pictureBox1.Height;
            float znear = 0.01f;
            float zfar = 100.0f;
            SlimDX.Matrix projectionMatrix = SlimDX.Matrix.PerspectiveFovLH(fov, aspect, znear, zfar);
            this.device.SetTransform(SlimDX.Direct3D9.TransformState.Projection, projectionMatrix);

            SlimDX.Matrix transformMatrix = SlimDX.Matrix.Identity;
            this.device.SetTransform(SlimDX.Direct3D9.TransformState.World, transformMatrix);

            this.device.BeginScene();

            for (int i = 0; i < this.mesh.GetMaterials().Length; ++i)
            {
                this.device.Material = this.mesh.GetMaterials()[i].MaterialD3D;
                this.mesh.DrawSubset(i);
                
            }
            this.device.EndScene();
        }
    }
}
